package elements;

import java.awt.Polygon;
import java.security.SecureRandom;

import scaler.Scaler;

import mover.GameMover;
import mover.SimpleMover;

public class GameElementFactory {
	private int randomSpeed = 0;
	private SecureRandom random;
	public enum Element {
		Square, Rectangle, Triangle, Diamond, Circle, Character
	}
	/**
	 * Used for getting an random element out of all possible elements
	 */
	public static final Element randomElement[] = new Element[0]; 
	public static final Element withoutChar[] =
			new Element[] { Element.Square, Element.Rectangle, Element.Triangle, Element.Diamond, Element.Circle }; 

	public GameElementFactory() {
		random = new SecureRandom();
	}

	public GamePolygon newGameSquare(GameMover mover, Scaler scaler, int size) {
		return new GamePolygon(
				new Polygon(new int[]{0, size, size, 0}, new int[]{0, 0, size, size}, 4),
				mover, scaler);
	}

	public GamePolygon newGameRectangle(GameMover mover, Scaler scaler, int height, int width) {
		return new GamePolygon(
				new Polygon(new int[]{0, width, width, 0}, new int[]{0, 0, height, height}, 4),
				mover, scaler);
	}

	public GamePolygon newNorthGameTriangle(GameMover mover,Scaler scaler, int height, int width) {
		int widthTmp = round(width);
		return new GamePolygon(
				new Polygon(new int[]{widthTmp/2, widthTmp, 0}, new int[]{0, height, height}, 3),
				mover, scaler);
	}

	public GamePolygon newSouthGameTriangle(GameMover mover, Scaler scaler, int height, int width) {
		int widthTmp = round(width);
		return new GamePolygon(
				new Polygon(new int[]{widthTmp/2, widthTmp, 0}, new int[]{height, 0, 0}, 3),
				mover, scaler);
	}

	public GamePolygon newGameDiamond(GameMover mover,Scaler scaler, int height, int width) {
		int widthTmp = round(width);
		return new GamePolygon(new Polygon(new int[]{widthTmp/2, widthTmp, widthTmp/2, 0}, new int[]{0, height/2, height, height/2}, 4),
				mover, scaler);
	}

	public GameCharacter newGameCharacter(GameMover mover,Scaler scaler, String c) {
		return new GameCharacter(mover,scaler, c);
	}

	public GameElement newGameCircle(GameMover mover, Scaler scaler, int diameter) {
		return new GameCircle(mover, scaler, diameter);
	}

	public static GameMover no_movement() { return GameElement.NO_MOVEMENT; }
	public static GameMover north() { return new SimpleMover(0, -1); }
	public static GameMover south() { return new SimpleMover(0, 1); }
	public static GameMover east() { return new SimpleMover(1, 0); }
	public static GameMover west() { return new SimpleMover(-1, 0); }
	public static GameMover north_east() { return new SimpleMover(-1, 1); }
	public static GameMover south_east() { return new SimpleMover(1, 1); }
	public static GameMover south_west() { return new SimpleMover(1, -1); }
	public static GameMover north_west() { return new SimpleMover(-1, -1); }

	/**
	 * Returns a random SimpleMover
	 * @return
	 */
	public GameMover newRandomMover() {
		GameMover mover = null;

		switch(random.nextInt(7)) {
		case 0: mover = north(); break;
		case 1: mover = south(); break;
		case 2: mover = east(); break;
		case 3: mover = west(); break;
		case 4: mover = north_east(); break;
		case 5: mover = south_east(); break;
		case 6: mover = south_west(); break;
		case 7: mover = north_west(); break;
		}

		if(randomSpeed != 0) {
			mover.setXMult(randomSpeed);
			mover.setYMult(randomSpeed);
			randomSpeed = 0;
		}
		
		return mover;
	}

	/**
	 * Creates randomly one of the elements which are listed in the ElementArray
	 * Height and width are choosen randomly
	 * @param elements The list of possible elements
	 * @return A random GameElement
	 */
	public GameElement newRandomElement(Element elements[], Scaler scaler) {
		return newRandomElement(newRandomMover(), scaler , elements);
	}

	public GameElement newRandomElement(Element elements[]){
		return this.newRandomElement(elements, Scaler.NO_SCALING);
	}

	/**
	 * Creates randomly one of the the elements which are listed in the ElementArray
	 * Height and width are choosen randomly.
	 * @param mover The Mover for the random GameElement
	 * @param elements The list of possible elements
	 * @return A random GameElement
	 */
	public GameElement newRandomElement(GameMover mover,Scaler scaler, Element elements[]) {		
		return newRandomElement(mover,scaler, 50 + random.nextInt(50), 50 + random.nextInt(50), elements);
	}

	/**
	 * Creates randomly one of the the elements which are listed in the ElementArray
	 * @param mover The Mover for the random GameElement
	 * @param elements The list of possible elements
	 * @return A random GameElement
	 */
	public GameElement newRandomElement(GameMover mover, Scaler scaler, int height, int width, Element elements[]) {
		GameElement ele = null;

		switch(elements[random.nextInt(elements.length)]) {
		case Square: ele = newGameSquare(mover,scaler, height); break;
		case Rectangle: ele = newGameRectangle(mover,scaler, height, width); break;
		case Triangle: 
			if(random.nextBoolean()) {
				ele = newNorthGameTriangle(mover,scaler, height, width);
			} else {
				ele = newSouthGameTriangle(mover,scaler, height, width);
			} break;
		case Diamond: ele = newGameDiamond(mover,scaler, height, width); break;
		case Circle: ele = newGameCircle(mover,scaler, height); break;
		case Character: ele = newGameCharacter(mover,scaler, GameCharacter.RANDOM_CHAR); break;
		}

		return ele;
	}

	/**
	 * Sets the multipier for the Elementsspeed.
	 * Will be reseted to 1 after creating one element with a random mover.
	 */
	public void setRandomSpeed(int speed) {
		randomSpeed = speed;
	}

	private int round(int value) {
		return (value/2)*2 < value ? value++ : value;
	}
}
